<!--
 * @description 自定义文本-用于试题的题干和选项
 * @author dumeng
 * @date 2021/8/9
 -->
<template>
  <div class="custom-textarea-page">
    <template v-if="type === 'option'">
      <el-input
        :id="flag"
        v-model.trim="text"
        :disabled="disabled"
        :placeholder="placeholder"
        @focus="$emit('focus')"
        @input="$emit('input', $event)"
      >
        <el-button slot="append" :disabled="disabled" @click="handleUpload('img')">上传图片</el-button>
        <el-button slot="append" :disabled="disabled" @click="handleUpload('video')">上传视频</el-button>
        <el-button slot="append" :disabled="disabled" @click="handleUpload('audio')">上传音频</el-button>
        <el-button slot="append" @click="preview()">预览</el-button>
      </el-input>
    </template>
    <template v-else>
      <el-row>
        <el-col :span="14">
          <el-input
            :id="flag"
            v-model="text"
            type="textarea"
            :autosize="{minRows: 2}"
            :disabled="disabled"
            :placeholder="placeholder"
            @focus="$emit('focus')"
            @input="$emit('input', $event)"
          />
        </el-col>
        <el-col :span="10">
          <el-button :disabled="disabled" size="mini" style="margin-left: 10px;" @click="handleUpload('img')">上传图片
          </el-button>
          <el-button :disabled="disabled" size="mini" @click="handleUpload('video')">上传视频</el-button>
          <el-button :disabled="disabled" size="mini" @click="handleUpload('audio')">上传音频</el-button>
          <el-button size="mini" @click="preview()">预览</el-button>
        </el-col>
      </el-row>
    </template>
    <upload
      v-if="showUploadFile"
      ref="upload"
      :accept="uploadType | acceptType"
      :limit="1"
      :show-chunks="true"
      :multiple="false"
      :is-oss="uploadFile.isOss"
      :chunk-size="10000"
      @close="showUploadFile=false"
      @success="uploadSuccess"
    >
      <div slot="tip" class="upload-tip">
        <i class="el-icon-info" />
        :
        {{ uploadType| fileTips }}
      </div>
    </upload>
    <el-dialog
      v-el-drag-dialog
      :close-on-click-modal="false"
      :visible.sync="dialogUploadVisible"
      title="上传文件"
      center
      @close="closeUploadDialog()"
    >
      <!--      <el-radio-group v-model="linkSource" style="margin-bottom: 10px">
        <el-radio label="0">系统内上传</el-radio>
        <el-radio label="1">站外链接</el-radio>
      </el-radio-group>
      <div v-if="linkSource ==='0'">
        <el-button @click="showUploadFile=true">{{ fileName || '上传' }}</el-button>
      </div>
      <el-input
        v-else
        v-model.trim="linkPath"
        type="textarea"
        :rows="8"
        placeholder="请输入外链地址"
      />-->
      <el-button @click="showUploadFile=true">{{ fileName || '上传文件' }}</el-button>
      <h4>上传文件封面</h4>
      <image-upload
        :key="uploadFile.viewId"
        v-model="videoPoster"
        :preview-id="uploadFile.viewId"
        :forever="true"
        :width="654"
        :height="368"
        :view="uploadFile.view"
        :no-circle="true"
        :no-rotate="false"
        lang-type="zh"
        :is-oss="uploadFile.isOss"
        @changeOssPath="changeOssPath"
      />
      <span slot="footer" class="dialog-footer">
        <el-button style="padding: 8px 30px;" type="primary" @click="closeUploadDialog()">取消</el-button>
        <el-button style="padding: 8px 30px;" type="primary" @click="submitVideoUpload()">确认</el-button>
      </span>
    </el-dialog>
    <el-dialog
      v-if="dialogPreviewVisible"
      v-el-drag-dialog
      append-to-body
      :close-on-click-modal="false"
      :visible.sync="dialogPreviewVisible"
      title="预览"
      center
      @opened="openedDialog"
      @close="closePreviewDialog"
    >

      <div ref="previewDialog" class="custom-textarea-preview" v-html="previewHtml" />
    </el-dialog>

    <!--  查看音频、视频试题  -->
    <el-dialog
      v-el-drag-dialog
      append-to-body
      :close-on-click-modal="false"
      :visible.sync="dialogFileVisible"
      title="查看"
      center
      width="600px"
      @close="closeViewDialog"
    >
      <div class="custom-textarea-preview-view">
        <div v-if="fileType==='video'" id="videoPlayer" class="prism-player" />
        <audio
          v-else-if="fileType==='audio'"
          id="file-audio"
          :src="filePath"
          controls="controls"
          controlsList="nodownload"
        />
      </div>

    </el-dialog>
  </div>
</template>

<script>
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
import { mapGetters } from 'vuex'
import { exportSign } from '@/utils/fileImportOrExportSign'
import upload from '@/components/upload'
import defaultImg from './images/default.png'
import ImageUpload from '@/components/ImageUpload'

export default {
  name: 'Index',
  directives: { elDragDialog },
  components: { upload, ImageUpload },
  model: {
    prop: 'content',
    event: 'change'
  },
  props: {
    content: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: ''
    },
    flag: {
      type: String,
      required: true,
      default: ''
    },
    type: {
      type: String,
      required: true,
      default: 'content'
    }
  },
  computed: {
    ...mapGetters([
      'questionId'
    ])
  },
  filters: {
    fileTips(type) {
      return type === 'img' ? '只能上传图片' : type === 'video' ? '只能上传视频' : type === 'audio' ? '只能上传音频' : ''
    },
    acceptType(type) {
      return type === 'img' ? 'image/*' : type === 'video' ? 'video/*' : type === 'audio' ? 'audio/*' : ''
    }
  },
  data() {
    return {
      text: '',
      dialogPreviewVisible: false,
      dialogUploadVisible: false,
      loadingUpload: false,
      uploadType: 'img',

      uploadData: {
        questionId: '',
        fileType: ''
      },
      uploadFlag: {
        target: '',
        index: '',
        property: ''
      },
      linkSource: '0',
      linkPath: '',
      showUploadFile: false,
      fileData: '',
      fileName: '',
      defaultImg: 'this.src="' + defaultImg + '"',
      defaultPoster: require('../../images/cover.png'),
      // 预览视频、音频文件
      player: null,
      view: '/API-DOCUMENT/document/file/download',
      videoElementList: [],
      audioElementList: [],
      audioList: [],
      previewHtml: '',
      dialogFileVisible: false,
      fileType: '',
      filePath: '',
      uploadFile: {
        viewId: '',
        view: '/API-DOCUMENT/document/file/download?id=',
        imagecropperKey: 0,
        showUpload: -1, // 1视频 2图片 3附件
        accept: '',
        fileType: '',
        fileIndex: 0,
        // isOss: sessionStorage.getItem('FILE_SAVE_THIRD_CONFIG') || false
        isOss: false
      },
      videoPoster: ''// 上传视频的封面
    }
  },
  watch: {
    text: function(val) {
      this.$emit('change', val)
    }
  },
  created() {
    this.text = this.content
  },
  mounted() {
    const ths = this
    // 查看大图
    window.see_pic = function(e, src) {
      e.stopPropagation()
      // 如果是外链地址，直接查看
      if (e.currentTarget.getAttribute('src').indexOf('API-DOCUMENT') === -1 && !src.startsWith('http')) {
        e.currentTarget.setAttribute('src', this.view + `${exportSign({ id: src }).paramStr}`)
      }
      ths.picShow = true
    }

    /**
     * 获取页面所有的video
     * 根据播放video的 id 区分，点击播放按钮后，id一样的播放，不一样的 暂停
     *
     */

    window.handlePlay = function(event, type, id) {
      if (document.getElementsByTagName('audio').length > 0) {
        for (let i = 0; i < document.getElementsByTagName('audio').length; i++) {
          if (document.getElementsByTagName('audio')[i].id == id) {
            document.getElementsByTagName('audio')[i].play()
          } else {
            document.getElementsByTagName('audio')[i].pause()
          }
        }
      }
    }
    window.handleVideoPlay = function(event, type, id, src, poster) {
      ths.fileType = type
      ths.filePath = src
      ths.dialogFileVisible = true
      if (type === 'video') {
        ths.$nextTick(() => {
          ths.createPlayer(poster)
        })
      }
    }
  },
  methods: {
    handleUploadFile() {
      this.showUploadFile = true
    },
    // 生成随机字符串
    randomString(len) {
      len = len || 32
      var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
      /** **默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
      var maxPos = chars.length
      var pwd = ''
      for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos))
      }
      return pwd
    },
    /**
     * 为防止xss攻击，所以当前组件的输入内容包含ttsxtag的自定义标签
     * 为预览成功要转换为浏览器可识别的img或video原生标签
     *
     */
    handlePreview(str) {
      this.videoElementList = []
      // 防止xss攻击将<转为&lt;
      str = str.replace(/</g, '&lt;')
      // 自定义标签正则，可以过滤出文本中所有该标签
      var patt = /&lt;ttsxtag[^>]+type=['"]([^'"]+)['"]+\/>/g
      // src正则，可以取出src后面的id
      var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i
      var posterReg = /poster=[\'\"]?([^\'\"]*)[\'\"]?/i
      var result = []
      var temp
      // 将文本中的所有自定义标签取出放到数组中
      while ((temp = patt.exec(str)) != null) {
        result.push({ type: temp[1], index: temp.index, str: temp[0] })
      }
      // 防止位置发生变化，从后向前循环该数组
      for (let i = result.length - 1; i >= 0; i--) {
        const item = result[i]
        let itemSrc = item.str.match(srcReg)[1] // 得到每个自定义标签中的id
        // 判断src中是否包含http,如果包含认为是完整的链接地址，如果不是，将id替换为接口+id
        if (itemSrc.indexOf('http') === -1) {
          const srcPath = this.view + `${exportSign({ id: itemSrc }).paramStr}`
          item.str = item.str.replace(itemSrc, srcPath)
          itemSrc = srcPath
        }

        // 将ttsxtag标签替换为原生标签
        if (item.type === 'img') {
          item.str = item.str.replace(/&lt;ttsxtag/g, `<img onclick="see_pic(event,'${itemSrc}')" onerror=${this.defaultImg}`)
        } else if (item.type === 'audio') {
          const obj = {
            id: this.randomString(6),
            src: itemSrc
          }
          item.str = item.str.replace(/&lt;ttsxtag/g, `<audio class="my-audio"  id=${obj.id}  onplay="handlePlay(event,'audio','${obj.id}')" `) + '</audio>'
        } else if (item.type === 'video') {
          let itemPoster = this.defaultPoster
          if (item.str.match(posterReg)) {
            itemPoster = item.str.match(posterReg)[1] // 得到每个自定义标签中的poster
            // 判断poster中是否包含http,如果包含认为是完整的链接地址，如果不是，将poster字段替换为接口+poster
            if (itemPoster.indexOf('http') === -1) {
              const posterPath = this.view + `${exportSign({ id: itemPoster }).paramStr}`
              item.str = item.str.replace(itemPoster, posterPath)
              itemPoster = posterPath
            }
          }

          const obj = {
            id: this.randomString(6),
            player: null,
            src: itemSrc,
            poster: itemPoster
          }
          item.str = item.str.replace(/&lt;ttsxtag/g, `<div class="my-video not-start" style="background-image: url(${obj.poster})" onclick="handleVideoPlay(event,'video','${obj.id}','${obj.src}','${obj.poster}')"  id=${obj.id}`) + '</div>'
        }

        // 插入到原始位置
        str = this.insertStr(str, item.index, item.str)
      }
      var reg1 = /&lt;ttsxtag[^>]*>/gi
      var reg2 = /type=['"]([^'"]+)['"]/g
      // 将以下标签转成HTML支持的标签
      var reg3 = /&lt;br/g
      var reg4 = /&lt;b(.*?)&lt;\/b>/g
      var reg5 = /&lt;i(.*?)&lt;\/i>/g
      var reg6 = /&lt;u(.*?)&lt;\/u>/g
      // 将自定义标签其中的type属性删除、支持的标签转义
      const endStr = str.replace(reg1, '').replace(reg2, '').replace(reg3, '<br').replace(reg4, '<b$1</b>').replace(reg5, '<i$1</i>').replace(reg6, '<u$1</u>')
      return endStr
    },
    /**
     * 上传文件
     * @param t === img ? 图片 ： 视频
     */
    handleUpload(t) {
      this.uploadType = t
      this.uploadData.fileType = t === 'img' ? 'IMAGE' : t === 'video' ? 'VIDEO' : t === 'audio' ? 'AUDIO' : ''
      // this.uploadData.questionId = this.questionId

      if (t === 'video') {
        this.dialogUploadVisible = true
      } else {
        this.handleUploadFile()
      }
    },
    changeOssPath(path) {
      this.uploadFile.viewId = path
    },
    uploadSuccess(id, file) {
      this.$message({
        message: '上传成功',
        type: 'success'
      })
      this.showUploadFile = false
      this.fileData = this.uploadFile.isOss ? file[0].ossPath : id
      this.fileName = file[0].name
      this.submitUpload()
    },
    uploadError(err) {
      this.loadingUpload = false
      this.$message.error(err || '网络异常')
    },
    /**
     * 关闭上传弹框
     */
    closeUploadDialog() {
      this.dialogUploadVisible = false
      this.linkSource = '0'
      this.linkPath = ''
      this.fileName = ''
      this.fileData = ''
      this.videoPoster = ''
      this.uploadFile.viewId = ''
    },
    /**
     * 验证外链地址是否正确
     * @param url
     */
    verifyUrl(url) {
      const reg = /^((http|https):\/\/)?(([A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\.)+([A-Za-z]+)[/\?\:]?.*$/
      if (!reg.test(url)) {
        this.$message.error('请填写正确的链接地址')
        return false
      } else {
        return true
      }
    },
    /**
     * 上传视频
     * */
    submitVideoUpload() {
      if (this.fileData) {
        if (this.uploadFile.isOss) {
          this.addVideo(this.fileData, this.uploadFile.viewId)
        } else {
          this.addVideo(this.fileData, this.videoPoster)
        }
        this.closeUploadDialog()
      } else {
        this.$message({
          type: 'warning',
          message: '请上传文件'
        })
      }
    },
    submitUpload() {
      if (this.linkSource === '1') {
        if (!this.linkPath.trim()) {
          this.$message.error('请填写链接地址')
          return
        }
        if (!this.verifyUrl(this.linkPath.trim())) {
          return
        }
        if (this.uploadType === 'img') {
          this.addImage(this.linkPath.trim())
        } else if (this.uploadType === 'audio') {
          this.addAudio(this.linkPath.trim())
        }/* else if (this.uploadType === 'video') {
          this.addVideo(this.linkPath.trim())
        } */
        this.closeUploadDialog()
      } else {
        if (this.fileData) {
          if (this.uploadType === 'img') {
            this.addImage(this.fileData)
            this.closeUploadDialog()
          } else if (this.uploadType === 'audio') {
            this.addAudio(this.fileData)
            this.closeUploadDialog()
          }/* else if (this.uploadType === 'video') {
            this.addVideo(this.fileData, this.videoPoster)
          }*/
        } else {
          this.$message({
            type: 'warning',
            message: '请上传文件'
          })
        }
      }
    },
    insertStr(soure, start, newStr) {
      return soure.slice(0, start) + newStr + soure.slice(start)
    },
    addImage(id) {
      const index = this.getTxt1CursorPosition()
      const tag = `<ttsxtag src="${id}" type="img"/>`
      this.text = this.insertStr(this.text, index, tag)
    },
    addVideo(id, poster) {
      const index = this.getTxt1CursorPosition()
      let tag = ''
      if (poster) {
        tag = `<ttsxtag src="${id}" poster="${poster}" type="video"/>`
      } else {
        tag = `<ttsxtag src="${id}" type="video"/>`
      }
      this.text = this.insertStr(this.text, index, tag)
    },
    addAudio(id) {
      const index = this.getTxt1CursorPosition()
      const tag = `<ttsxtag src="${id}" controls="controls" controlsList="nodownload"   type="audio"/>`
      this.text = this.insertStr(this.text, index, tag)
    },
    getTxt1CursorPosition() {
      var oTxt1 = document.getElementById(this.flag)
      var cursurPosition = -1
      if (oTxt1.selectionStart) { // 非IE浏览器
        cursurPosition = oTxt1.selectionStart
      } else { // IE
        try {
          var range = document.selection.createRange()
          range.moveStart('character', -oTxt1.value.length)
          cursurPosition = range.text.length
        } catch (err) {
          cursurPosition = 0
        }
      }
      return cursurPosition
    },

    preview() {
      this.dialogPreviewVisible = true
      this.previewHtml = this.handlePreview(this.text)
    },
    /**
     * dialog显示后
     */
    openedDialog() {
    },
    closePreviewDialog() {
      this.previewHtml = ''
    },
    closeViewDialog() {
      this.filePath = ''
      this.fileType = ''
      if (this.player) {
        this.player.dispose() // 重置 video
        this.player = null
      }
    },

    createPlayer(poster) {
      const ths = this
      if (this.player == null) {
        this.player = new Aliplayer({
          id: 'videoPlayer',
          autoplay: false,
          source: ths.filePath,
          // format: 'm3u8',
          preload: true, // 播放器自动加载
          useH5Prism: true,
          skinLayout: [
            { name: 'bigPlayButton', align: 'cc' },
            {
              name: 'H5Loading',
              align: 'cc'
            },
            { name: 'errorDisplay', align: 'tlabs', x: 0, y: 0 },
            { name: 'infoDisplay' },
            { name: 'tooltip', align: 'blabs', x: 0, y: 56 },
            { name: 'thumbnail' },
            {
              name: 'controlBar',
              align: 'blabs',
              x: 0,
              y: 0,
              children: [
                { name: 'progress', align: 'blabs', x: 0, y: 44 },
                { name: 'playButton', align: 'tl', x: 15, y: 12 },
                { name: 'timeDisplay', align: 'tl', x: 10, y: 7 },
                { name: 'fullScreenButton', align: 'tr', x: 10, y: 12 }
                // {name:"subtitle", align:"tr",x:15, y:12},
                // { name: 'setting', align: 'tr', x: 15, y: 12 },
                // { name: 'volume', align: 'tr', x: 5, y: 10 }
              ]
            }
          ],
          cover: poster
        }, function(player) {
          player.play()
        })
      } else {
        this.player.loadByUrl(this.filePath)
      }
    }

  }

}
</script>

<style lang="scss">
.custom-textarea-page {
  .el-input-group__append .el-button:nth-child(2) {
    position: relative;

    &:after {
      content: '';
      display: block;
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      width: 1px;
      background-color: #e5e5e5;
    }

    &:before {
      content: '';
      display: block;
      position: absolute;
      right: 0;
      top: 0;
      bottom: 0;
      width: 1px;
      background-color: #e5e5e5;
    }
  }
}

.custom-textarea-preview {
  min-height: 200px;
  max-height: calc(100vh - 150px);
  overflow-y: auto;

  img, video {
    width: 100% !important;
  }

  .my-video {
    height: auto;
    width: 100%;
    position: relative;
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;

    &.not-start {
      //background-color: #999;
      width: 200px;
      height: 112px;

      &:after {
        content: '';
        width: 44px;
        height: 44px;
        background: url("") no-repeat;
        background-size: 100% 100%;
        display: inline-block;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        color: #fff;
        font-size: 14px;
      }
    }
  }

}

.custom-textarea-preview-view {
  height: 500px;
  overflow-y: auto;

  .prism-player {
    height: 200px;
    width: auto;
  }
}
</style>
